#pragma once
#include <LibraryConfig.hpp>
//use lapack to do high level math

#include "zMatrix.hpp"

namespace zzz{
bool LUFactorization(zMatrix<double,zColMajor> &mat, zMatrix<long,zColMajor> &IPIV, long *info=NULL);

bool CholeskyFactorization(zMatrix<double,zColMajor> &A, long *info=NULL);
  
// ATTENTION: original value will not be kept even if failed
bool Invert(zMatrix<double,zColMajor> &mat, long *info=NULL);
// Matlab style interface
inline zMatrix<double,zColMajor> Inv(const zMatrixBaseR<double,zColMajor> &mat, long *info=NULL) {
  zMatrix<double,zColMajor> x(mat);
  if (Invert(x, info))
    return x;
  else
    return zMatrix<double,zColMajor>();
}

bool SVD(zMatrix<double,zColMajor> &A, zMatrix<double,zColMajor> &U, zMatrix<double,zColMajor> &S, zMatrix<double,zColMajor> &VT, long *info=NULL);

bool EigenSym(zMatrix<double,zColMajor> &A, zMatrix<double,zColMajor> &e, long *info=NULL);

double Det(zMatrix<double,zColMajor> &A);

// return eigen vector are in each column corresponding to eigen value order
bool EigRight(zMatrix<double,zColMajor> &A, zMatrix<double,zColMajor> &eigenVector, zMatrix<double,zColMajor> &eigenValueReal, zMatrix<double,zColMajor> &eigenValueImag, long *info=NULL);

bool SolveLinearLeastSquare(zMatrix<double,zColMajor> &A, zMatrix<double,zColMajor> &B_X, long *info=NULL);

bool SolveLinearLeastSquare2(zMatrix<double,zColMajor> &A, zMatrix<double,zColMajor> &B_X, long *info=NULL);

bool SolveLinear(zMatrix<double,zColMajor> &A, zMatrix<double,zColMajor> &B_X, long *info=NULL);
}

